package main

import (
	"log"
	"moft/admin"
	"moft/database"
	"moft/handler"
	"moft/middleware"
	"net"

	"github.com/gin-gonic/gin"
	"github.com/quixote-liu/config"
)

var conf = config.CONF()

func main() {
	// parse configuration.
	if err := conf.LoadConfiguration("./config.conf"); err != nil {
		log.Printf("parse configuration failed: %v", err)
		return
	}

	// init database.
	dbSvc, err := database.InitMysqlDatabase()
	if err != nil {
		log.Printf("init database failed: %v", err)
		return
	}
	defer func() {
		if err := dbSvc.Close(); err != nil {
			log.Printf("close database failed: %v", err)
		}
	}()
	if err := dbSvc.MigrateTables(); err != nil {
		log.Printf("migrate tables into mysql failed: %v", err)
		return
	}

	// init system admin user.
	if err := admin.Init(); err != nil {
		log.Printf("init system admin failed: %v", err)
		return
	}

	// setup routers.
	r := initRouters()

	host := conf.GetString("system", "host")
	port := conf.GetString("system", "port")
	server := net.JoinHostPort(host, port)
	log.Printf("start server on %s", server)
	log.Println(r.Run(server))
}

func initRouters() *gin.Engine {
	r := gin.Default()

	// public
	r.GET("/api/v1/health", handler.CheckHealth)
	r.GET("/api/v1/version", handler.GetVersion)

	// auth routers.
	{
		auth := handler.NewAuthHandler()
		group := r.Group("/api/v1/auth")
		group.POST("/login", auth.Login)
		group.POST("/logout", auth.Logout)
	}

	// role routers.
	{
		role := handler.NewRoleHandler()
		group := r.Group("/api/v1/roles")
		group.Use(middleware.Admin(), middleware.Session())
		group.POST("", role.Create)
		group.GET("", role.List)
		group.PUT("/:role_name", role.Update)
	}

	// user routers.
	{
		user := handler.NewUserHandler()
		group := r.Group("/api/v1/users")
		group.Use(middleware.Admin(), middleware.Session())
		group.GET("", user.List)
		group.POST("", user.Create)
		group.DELETE("/:user_id", user.Delete)
	}

	// client routers.
	{
		client := handler.NewClientHandler()
		group := r.Group("/api/v1/clients")
		group.Use(middleware.Admin(), middleware.Session())
		group.POST("", client.Create)
		group.PUT("", client.Update)
		group.PUT("/:client_name", client.Enabled)
		group.GET("", client.List)
		group.GET("/cleint_name", client.FindByName)
	}

	// ticket routers.
	{
		ticket := handler.NewTicketHandler()
		group := r.Group("/api/v1/tickets")
		group.Use(middleware.Admin(), middleware.Session())
		group.POST("", ticket.CreateTicket)
		group.PUT("", ticket.Update)
		group.DELETE("/:ticket_id", ticket.Delete)
		group.GET("", ticket.List)
	}

	return r
}
